use crate::ass::{Alignment, AssEvent, AssStyle};
use napi_derive_ohos::napi;
use rsubs_lib::SSA;
use std::{fs::File, io::Read};

#[napi]
pub struct ParseAss {
    path: String,
    instance: Option<SSA>,
}

#[napi]
impl ParseAss {
    #[napi(constructor)]
    pub fn new(path: String) -> Self {
        ParseAss {
            path,
            instance: None,
        }
    }

    #[napi]
    pub async unsafe fn init(&mut self) {
        if let Ok(mut file) = File::open(&self.path) {
            let mut contents = String::new();
            if let Ok(_) = file.read_to_string(&mut contents) {
                if let Ok(result) = SSA::parse(contents) {
                    self.instance = Some(result);
                }
            }
        }
    }

    #[napi]
    pub async unsafe fn read_events(&mut self) -> Vec<AssEvent> {
        let mut list: Vec<AssEvent> = vec![];
        if let Some(result) = &self.instance {
            for event in &result.events {
                list.push(AssEvent {
                    layer: event.layer,
                    start: event.start.millisecond(),
                    end: event.end.millisecond(),
                    style: event.style.to_string(),
                    name: event.name.to_string(),
                    margin_left: event.margin_l as f64,
                    margin_right: event.margin_r as f64,
                    margin_top: event.margin_v as f64,
                    margin_bottom: event.margin_v as f64,
                    effect: event.effect.to_string(),
                    text: event.text.to_string(),
                });
            }
        }
        list
    }

    #[napi]
    pub async unsafe fn read_fonts(&mut self) -> Vec<String> {
        let mut list: Vec<String> = vec![];
        if let Some(result) = &self.instance {
            for font in &result.fonts {
                list.push(font.to_string());
            }
        }
        list
    }

    #[napi]
    pub async unsafe fn read_graphics(&mut self) -> Vec<String> {
        let mut list: Vec<String> = vec![];
        if let Some(result) = &self.instance {
            for graphic in &result.graphics {
                list.push(graphic.to_string());
            }
        }
        list
    }

    #[napi]
    pub async unsafe fn read_styles(&mut self) -> Vec<AssStyle> {
        let mut list: Vec<AssStyle> = vec![];
        if let Some(result) = &self.instance {
            for style in &result.styles {
                let primary_color = style
                    .primary_color
                    .map(|f| format!("#{:02X}{:02X}{:02X}{:02X}", f.r, f.g, f.b, f.a));
                let secondary_color = style
                    .secondary_color
                    .map(|f| format!("#{:02X}{:02X}{:02X}{:02X}", f.r, f.g, f.b, f.a));
                let outline_color = style
                    .outline_color
                    .map(|f| format!("#{:02X}{:02X}{:02X}{:02X}", f.r, f.g, f.b, f.a));
                let back_color = style
                    .back_color
                    .map(|f| format!("#{:02X}{:02X}{:02X}{:02X}", f.r, f.g, f.b, f.a));
                list.push(AssStyle {
                    name: style.name.to_string(),
                    font_name: style.fontname.to_string(),
                    font_size: style.fontsize as f64,
                    primary_color,
                    secondary_color,
                    outline_color,
                    back_color,
                    bold: style.bold,
                    italic: style.italic,
                    underline: style.underline,
                    strikeout: style.strikeout,
                    scale_x: style.scale_x as f64,
                    scale_y: style.scale_y as f64,
                    spacing: style.spacing as f64,
                    angle: style.angle as f64,
                    border_style: style.border_style,
                    outline: style.outline as f64,
                    shadow: style.shadow as f64,
                    alignment: Alignment::from(style.alignment),
                    margin_left: style.margin_l as f64,
                    margin_right: style.margin_r as f64,
                    margin_top: style.margin_v as f64,
                    margin_bottom: style.margin_v as f64,
                    encoding: style.encoding as f64,
                });
            }
        }
        list
    }
}
